package com.java.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.java.common.enums.OrderStatusEnum;
import com.java.common.enums.YseOrNo;
import com.java.common.utils.PageUtils;
import com.java.common.utils.Query;
import com.java.mapper.OrdersDao;
import com.java.pojo.*;
import com.java.pojo.bo.SubmitOrderBO;
import com.java.pojo.vo.MerchantOrdersVO;
import com.java.pojo.vo.OrderVO;
import com.java.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service("ordersService")
public class OrdersServiceImpl extends ServiceImpl<OrdersDao, Orders> implements OrdersService {
    @Autowired
    private UserAddressService addressService;
    @Autowired
    private ItemsSpecService specService;
    @Autowired
    private ItemsService itemsService;
    @Autowired
    private ItemsImgService imgService;
    @Autowired
    private OrderItemsService orderItemsService;
    @Autowired
    private OrderStatusService orderStatusService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<Orders> page = this.page(
                new Query<Orders>().getPage(params),
                // 拼接查询条件
                new LambdaQueryWrapper<Orders>()
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public MerchantOrdersVO createOrder(SubmitOrderBO submitOrderBO) {
        String userId = submitOrderBO.getUserId();
        String addressId = submitOrderBO.getAddressId();
        String itemSpecIds = submitOrderBO.getItemSpecIds();
        Integer payMethod = submitOrderBO.getPayMethod();
        String leftMsg = submitOrderBO.getLeftMsg();
        // 包邮费用设置为0
        Integer postAmount = 0;

        // 保存订单
        Snowflake snowflake = IdUtil.getSnowflake(1, 1);
        long id = snowflake.nextId();
        Orders orders = new Orders();
        orders.setId(String.valueOf(id));
        orders.setUserId(userId);

        UserAddress address = addressService.getOne(new LambdaQueryWrapper<UserAddress>().eq(UserAddress::getId, addressId).eq(UserAddress::getUserId, userId));
        orders.setReceiverName(address.getReceiver());
        orders.setReceiverMobile(address.getMobile());
        orders.setReceiverAddress(address.getProvince() + " " + address.getCity() + " " + address.getDistrict() + " " + address.getDetail());
        orders.setPostAmount(postAmount);
        orders.setPayMethod(payMethod);
        orders.setLeftMsg(leftMsg);

        // 根据itemSpecIds保存订单商品信息表
        String[] itemSpecIdArr = itemSpecIds.split(",");
        Integer totalAmount = 0;    // 商品原价累计
        Integer realPayAmount = 0;  // 优惠后的实际支付价格累计
        for (String itemSpecId : itemSpecIdArr) {

            // TODO 整合redis后，商品购买的数量重新从redis的购物车中获取
            int buyCounts = 1;

            // 2.1 根据规格id，查询规格的具体信息，主要获取价格
            ItemsSpec itemSpec = specService.getById(itemSpecId);
            totalAmount += itemSpec.getPriceNormal() * buyCounts;
            realPayAmount += itemSpec.getPriceDiscount() * buyCounts;

            // 2.2 根据商品id，获得商品信息以及商品图片
            String itemId = itemSpec.getItemId();
            Items item = itemsService.getById(itemId);
            String imgUrl = imgService.getOne(new LambdaQueryWrapper<ItemsImg>().eq(ItemsImg::getItemId,itemId).eq(ItemsImg::getIsMain,YseOrNo.YES.code)).getUrl();

            // 2.3 循环保存子订单数据到数据库
            String subOrderId = String.valueOf(snowflake.nextId());
            OrderItems subOrderItem = new OrderItems();
            subOrderItem.setId(subOrderId);
            subOrderItem.setOrderId(orders.getId());
            subOrderItem.setItemId(itemId);
            subOrderItem.setItemName(item.getItemName());
            subOrderItem.setItemImg(imgUrl);
            subOrderItem.setBuyCounts(buyCounts);
            subOrderItem.setItemSpecId(itemSpecId);
            subOrderItem.setItemSpecName(itemSpec.getName());
            subOrderItem.setPrice(itemSpec.getPriceDiscount());
            orderItemsService.save(subOrderItem);

            // 2.4 在用户提交订单以后，规格表中需要扣除库存
            itemsService.decreaseItemSpecStock(itemSpecId, buyCounts);
        }

        orders.setTotalAmount(totalAmount);
        orders.setRealPayAmount(realPayAmount);
        this.save(orders);

        // 保存订单状态
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderId(orders.getId());
        orderStatus.setOrderStatus(OrderStatusEnum.WAIT_PAY.type);
        orderStatus.setCreatedTime(new Date());
        orderStatusService.save(orderStatus);

        // 4. 构建商户订单，用于传给支付中心
        MerchantOrdersVO merchantOrdersVO = new MerchantOrdersVO();
        merchantOrdersVO.setMerchantOrderId(orders.getId());
        merchantOrdersVO.setMerchantUserId(userId);
        merchantOrdersVO.setAmount(realPayAmount + postAmount);
        merchantOrdersVO.setPayMethod(payMethod);

        return merchantOrdersVO;
    }

    /**
     * 修改订单状态
     */
    @Override
    @Transactional
    public void updateOrderStatus(String orderId, Integer status) {
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderId(orderId);
        orderStatus.setOrderStatus(status);
        orderStatus.setPayTime(new Date());
        orderStatusService.updateById(orderStatus);
    }

    @Override
    @Transactional
    public void autoCloseOrder() {
        List<OrderStatus> closeOrders = orderStatusService.getAutoCloseOrders();
        for (OrderStatus closeOrder : closeOrders) {
            closeOrder.setOrderStatus(OrderStatusEnum.CLOSE.type);
            closeOrder.setCloseTime(new Date());
        }
        orderStatusService.updateBatchById(closeOrders);
    }

}